<?php
// +----------------------------------------------------------------------
// | HkCms 后台用户角色表
// +----------------------------------------------------------------------
// | Copyright (c) 2012-2019 http://www.hkcms.cn, All rights reserved.
// +----------------------------------------------------------------------
// | Author: 广州恒企教育科技有限公司 <admin@hkcms.cn>
// +----------------------------------------------------------------------

namespace app\admin\model;

use common\model\Model;

class Role extends Model
{
    /**
     * 根据角色ID返回全部权限
     * @param integer $roleid 角色ID
     * @return array
     */
    public function getAccessList($roleid)
    {
        $priv_data = array();
        $data = model("admin/Access")->getAccessList($roleid);
        if (empty($data)) {
            return $priv_data;
        }
        foreach ($data as $k => $rs) {
            $priv_data[$k] = array(
                'role_id' => $rs['role_id'],
                'app' => $rs['app'],
                'controller' => $rs['controller'],
                'action' => $rs['action'],
            );
        }
        return $priv_data;
    }

    /**
     * 通过递归的方式获取该角色下的全部子角色
     * @param integer $id
     * @return string
     */
    public function getArrchildid($id)
    {
        if (empty($this->roleList)) {
            $this->roleList = $this->getTreeArray();
        }
        $arrchildid = $id;
        if (is_array($this->roleList)) {
            foreach ($this->roleList as $k => $cat) {
                if ($cat['parentid'] && $k != $id && $cat['parentid'] == $id) {
                    $arrchildid .= ',' . $this->getArrchildid($k);
                }
            }
        }
        return $arrchildid;
    }

    /**
     * 返回Tree使用的数组
     * @return array
     */
    public function getTreeArray()
    {
        $roleList = array();
        $roleData = $this->order(array("listorder" => "asc", "id" => "desc"))->select()->toArray();
        foreach ($roleData as $rs) {
            $roleList[$rs['id']] = $rs;
        }
        return $roleList;
    }

    /**
     * 根据角色Id获取角色名
     * @param int $roleId 角色id
     * @return string 返回角色名
     */
    public function getRoleIdName($roleId)
    {
        return $this->where(array('id' => $roleId))->value('name');
    }

    /**
     * 返回select选择列表
     * @param int $parentid 父节点ID
     * @param string $selectStr 是否要 <select></select>
     * @return string
     */
    public function selectHtmlOption($parentid = 0, $selectStr = '') 
    {
        $tree = new \libs\util\Tree();

        $tree->icon = array('&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ ');

        $tree->nbsp = '&nbsp;&nbsp;&nbsp;';

        $str = "'<option value='\$id' \$selected>\$spacer\$name</option>";

        $tree->init($this->getTreeArray());

        if ($selectStr) {

            $html = '<select ' . $selectStr . '>';

            $html.=$tree->get_tree(0, $str, $parentid);

            $html.='</select>';
            
            return $html;
        }
        return $tree->get_tree(0, $str, $parentid);
    }


    /**
     * 删除角色
     * @param int $roleid 角色ID
     * @return boolean
     */
    public function roleDelete($roleid) 
    {
        if (empty($roleid) || $roleid == 1) {

            $this->error = '超级管理员角色不能被删除！';

            return false;
        }

        //角色信息
        $info = $this->where(array('id' => $roleid))->find();

        if (empty($info)) {

            $this->error = '该角色不存在！';

            return false;
        }

        //子角色列表
        $child = explode(',', $this->getArrchildid($roleid));

        if (count($child) > 1) {

            $this->error = '该角色下有子角色，请删除子角色才可以删除！';

            return false;
        }

        $status = $this->where('id',$roleid)->delete();

        if ($status !== false) {

            //删除access中的授权信息
            return model('admin/Access')->where('role_id',$roleid)->delete() !== false ? true : false;
        }

        return false;
    }


    /**
     * 检查指定菜单是否有权限
     * @param type $data menu表中数组，单条
     * @param type $roleid 需要检查的角色ID
     * @param type $priv_data 已授权权限表数据
     * @return boolean
     */
    public function isCompetence($data, $roleid, $priv_data = array()) 
    {

        $priv_arr = array('app', 'controller', 'action');

        if ($data['app'] == '') {

            return false;
        }

        if (empty($priv_data)) {

            //查询已授权权限
            $priv_data = $this->getAccessList($roleid);
        }

        if (empty($priv_data)) {

            return false;
        }

        //菜单id
        $menuid = $data['id'];

        //菜单类型
        $type = $data['type'];

        //去除不要的数据
        foreach ($data as $key => $value) {

            if (!in_array($key, $priv_arr)) {

                unset($data[$key]);
            }
        }
        $competence = array(

            'role_id' => $roleid,

            'app' => $data['app'],
        );

        //如果是菜单项加上菜单Id用以区分，保持唯一
        if ($type == 0) {

            $competence["controller"] = $data['controller'] . $menuid;

            $competence["action"] = $data['action'] . $menuid;
        } else {

            $competence["controller"] = $data['controller'];

            $competence["action"] = $data['action'];
        }

        //检查是否在已授权列表中
        $implode = implode('', $competence);

        $info = in_array(implode('', $competence), $this->privArrStr($priv_data));

        if ($info) {

            return true;
        } else {

            return false;
        }
    }

    /**
     * 按规则排序组合
     * @param type $priv_data
     * @return array
     */
    private function privArrStr($priv_data) 
    {
        $privArrStr = array();

        if (empty($priv_data)) {

            return $privArrStr;

        }

        foreach ($priv_data as $rs) {

            $competence = array(

                'role_id' => $rs['role_id'],

                'app' => $rs['app'],

                'controller' => $rs['controller'],

                'action' => $rs['action'],
            );

            $privArrStr[] = implode('', $competence);
        }
        
        return $privArrStr;
    }
}